home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / cpp114.zoo / src / input.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-20  |  3.7 KB  |  187 lines

  1.  
  2. /*---------------------------------------------------------------------*\
  3. |                                    |
  4. | CPP -- a stand-alone C preprocessor                    |
  5. | Copyright (c) 1993-95 Hacker Ltd.        Author: Scott Bigham    |
  6. |                                    |
  7. | Permission is granted to anyone to use this software for any purpose    |
  8. | on any computer system, and to redistribute it freely, with the    |
  9. | following restrictions:                        |
  10. | - No charge may be made other than reasonable charges for repro-    |
  11. |     duction.                                |
  12. | - Modified versions must be clearly marked as such.            |
  13. | - The author is not responsible for any harmful consequences of    |
  14. |     using this software, even if they result from defects therein.    |
  15. |                                    |
  16. | input.c -- line-level input routines                    |
  17. \*---------------------------------------------------------------------*/
  18.  
  19. #include <stdlib.h>
  20. #include <stddef.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include "global.h"
  24.  
  25. #define LINEBUF 128
  26.  
  27. char *cur_file;
  28. unsigned long last_line,    /* the last line we registered */
  29.   this_line,            /* the line we just read */
  30.   next_line;            /* the line we're about to read */
  31.  
  32. static char *the_line;
  33. static size_t the_size;
  34. char *next_c;
  35.  
  36. /*
  37.    trigraph() -- translate trigraph sequences in string |s|.  |s| is modified
  38.    in place.
  39. */
  40. static void trigraph(s)
  41.   register char *s;
  42. {
  43.   register char *t = s;
  44.  
  45.   while (*s) {
  46.     if (*s == '?' && s[1] == '?')
  47.       switch (s[2]) {
  48.       case '=':
  49.     *t++ = '#';
  50.     goto skip;
  51.       case '/':
  52.     *t++ = '\\';
  53.     goto skip;
  54.       case '\'':
  55.     *t++ = '^';
  56.     goto skip;
  57.       case '(':
  58.     *t++ = '[';
  59.     goto skip;
  60.       case ')':
  61.     *t++ = ']';
  62.     goto skip;
  63.       case '!':
  64.     *t++ = '|';
  65.     goto skip;
  66.       case '<':
  67.     *t++ = '{';
  68.     goto skip;
  69.       case '>':
  70.     *t++ = '}';
  71.     goto skip;
  72.       case '-':
  73.     *t++ = '~';
  74.       skip:s += 3;
  75.     break;
  76.       default:
  77.     *t++ = *s++;
  78.     } else
  79.       *t++ = *s++;
  80.   }
  81.   *t = '\0';
  82. }
  83.  
  84. /*
  85.    getline() -- read a line from the global input file |inf|, translate
  86.    trigraphs if necessary, collapse lines spliced with \<newline>, and strip
  87.    comments if necessary
  88. */
  89. char *getline()
  90. {
  91.   register char *s, *t;
  92.   ptrdiff_t dp;
  93.  
  94.   this_line = next_line;    /* tomorrow never arrives; it just becomes
  95.                    today */
  96.   if (!the_line)
  97.     the_line = mallok(the_size = LINEBUF);
  98.   s = the_line;
  99.   if (!fgets(s, the_size, inf)) {
  100.     return NULL;
  101.   }
  102.   if (do_trigraphs)
  103.     trigraph(s);
  104.   t = s + strlen(s);
  105.   next_line++;
  106.   for (;;) {
  107.     if (t > s && t[-1] == '\n') {
  108.       t--;
  109.       if (t > s && t[-1] == '\r')
  110.     t--;
  111.       if (t > s && t[-1] == '\\') {
  112.     t--;
  113.     next_line++;
  114.       } else
  115.     break;
  116.     }
  117.     if (the_size - (t - s) < LINEBUF) {
  118.       dp = t - s;
  119.       the_size += LINEBUF;
  120.       s = reallok(s, the_size);
  121.       t = s + dp;
  122.     }
  123.     if (!fgets(t, (int)(the_size - (t - s)), inf)) {
  124.       *t = '\0';
  125.       break;
  126.     }
  127.     if (do_trigraphs)
  128.       trigraph(t);
  129.     t += strlen(t);
  130.   }
  131.   *t++ = '\0';
  132.   the_line = next_c = s;
  133.   return s;
  134. }
  135.  
  136. /*
  137.    flush_line() -- discard the rest of the input line and any pushed-back
  138.    tokens
  139. */
  140. void flush_line()
  141. {
  142.   next_c = NULL;
  143.   flush_tokenizer();
  144. }
  145.  
  146. /*
  147.    rest_of_line() -- return a pointer to the remainder of the input line
  148. */
  149. char *rest_of_line()
  150. {
  151.   return next_c;
  152. }
  153.  
  154. /*
  155.    tokenize_string() -- convert the string pointed to by |s| into a list of
  156.    tokens.  If |s| is NULL, convert the remainder of the input line.
  157. */
  158. TokenP tokenize_string(s)
  159.   char *s;
  160. {
  161.   char *old_next_c = 0;
  162.   register TokenP T = NULL, t = NULL, tt;
  163.  
  164.   if (s) {
  165.     old_next_c = next_c;
  166.     next_c = s;
  167.   }
  168.   for (;;) {
  169.     tt = _one_token();
  170.     if (tt->type == EOL) {
  171.       free_token(tt);
  172.       break;
  173.     }
  174.     if (!T)
  175.       t = T = tt;
  176.     else
  177.       t = t->next = tt;
  178.   }
  179.   if (s)
  180.     next_c = old_next_c;
  181.   if (t) {
  182.     t->next = NULL;
  183.     clear_ws(T);
  184.   }
  185.   return T;
  186. }
  187.